home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
ada
/
gwuada_5.zip
/
adaed
/
spider
/
spider.adb
< prev
next >
Wrap
Text File
|
1993-02-04
|
8KB
|
298 lines
WITH Text_IO;
PACKAGE My_Int_IO IS NEW Text_IO.Integer_IO(Num => Integer);
WITH Text_IO;
WITH Calendar; -- standard Ada Package
USE Calendar;
WITH My_Int_IO;
PACKAGE BODY Spider IS
-- IMPLEMENTATION of Spider Graphics Package
-- with no ANSI colors
-- by John Dalbey December 1992
-- contributed to the public domain.
--
Screen_Depth : CONSTANT Integer := 24;
Screen_Width : CONSTANT Integer := 80;
TYPE Direction IS (north,east,south,west);
TYPE DirectionSymbols IS ARRAY (Direction) OF character;
TYPE Palette IS ARRAY (ScreenColors) OF character;
SUBTYPE Depth IS Integer RANGE 1..Screen_Depth;
SUBTYPE Width IS Integer RANGE 1..Screen_Width;
Column : width; -- spider's position
Row : depth; -- in the room.
Heading : Direction ; -- spider's direction
Ink : ScreenColors; -- color being drawn
DebugFlag : boolean := false; -- Is single stepping on?
RoomSize : depth; -- generated randomly
RowHi : depth := 22; -- room upper boundary for row
ColHi : width := 40; -- room upper boundary for column
Spidersym : constant character := '*'; -- asterisk
LoBound : constant integer := 1; -- room lower boundary
WindowOffset : constant integer := 20;
ColorSymbols : constant Palette := ('+','X','O','.'); -- ASCII symbols for color
Compass : constant DirectionSymbols := ('^','>','V','<');
PROCEDURE MoveCursor (Row : Depth;Column : Width) IS
-- Move the cursor to a particular row and column on the screen.
BEGIN
Text_IO.Put (Item => ASCII.ESC);
Text_IO.Put ("[");
My_Int_IO.Put (Item => Row, Width => 1);
Text_IO.Put (Item => ';');
My_Int_IO.Put (Item => Column, Width => 1);
Text_IO.Put (Item => 'f');
END MoveCursor;
PROCEDURE DrawStatus IS
BEGIN
-- Draw Status Box in upper left corner showing current direction.
MoveCursor (1,1);
Text_IO.Put (" --- ");
MoveCursor (2,1);
Text_IO.Put ("| |");
MoveCursor (3,1);
Text_IO.Put ("| |");
MoveCursor (4,1);
Text_IO.Put (" --- ");
END DrawStatus;
PROCEDURE DrawRoom IS
-- Draw the Spider's room (fixed size).
i: integer;
BEGIN
Text_IO.PUT (ASCII.ESC);
Text_IO.Put (Item => "[2J"); -- clear screen
MoveCursor (1,1);
-- Top Bar
Text_IO.Put (" ");
Text_IO.Put ("----------------------------------------- ");
Text_IO.New_Line;
FOR I in 1..21 LOOP
Text_IO.Put (" |");
Text_IO.Put (". . . . . . . . . . . . . . . . . . . . .|");
Text_IO.New_Line;
END LOOP;
Text_IO.Put (" ");
Text_IO.Put ("----------------------------------------- ");
DrawStatus;
END DrawRoom;
PROCEDURE DrawRoom (Size: depth) IS
-- Draw the Spider's room (variable size).
i: integer;
BEGIN
Text_IO.PUT (ASCII.ESC);
Text_IO.Put (Item => "[2J"); -- clear screen
MoveCursor (1,1);
-- Top Bar
Text_IO.Put (" ");
FOR i in 1..Size-1 LOOP
Text_IO.Put ("--");
END LOOP;
Text_IO.Put ("-");
Text_IO.New_Line;
-- Side Bars
FOR I in 1..Size LOOP
Text_IO.Put (" |");
FOR i in 1..Size-1 LOOP
Text_IO.Put (". ");
END LOOP;
Text_IO.Put (".|");
Text_IO.New_Line;
END LOOP;
-- Bottom Bar
Text_IO.Put (" ");
FOR i in 1..Size-1 LOOP
Text_IO.Put ("--");
END LOOP;
Text_IO.Put ("-");
DrawStatus;
END DrawRoom;
PROCEDURE ChgColor (NewColor : ScreenColors) IS
-- Change the color the spider is using.
BEGIN
Ink := NewColor;
MoveCursor (3,3);
Text_IO.Put (ColorSymbols(Ink));
END ChgColor;
PROCEDURE ShowDirection IS
-- Show the current direction
BEGIN
MoveCursor(2,3);
Text_IO.Put (Compass(heading));
END ShowDirection;
PROCEDURE ShowSpider IS
-- Show the spider symbol
BEGIN
MoveCursor (Row+1, Column+WindowOffset);
Text_IO.Put (SpiderSym);
MoveCursor (2,3); -- HIdecursor
END ShowSpider;
PROCEDURE Reset IS
-- Create a fixed size room and reset the spider.
BEGIN
DrawRoom;
Column := 21;
Row := 11;
Heading := south;
Green;
ShowSpider;
ShowDirection;
END Reset;
FUNCTION Random RETURN Integer IS
-- RAndom number generator based on clock time.
Now: Time;
Yr: Year_Number;
Mo: Month_Number;
Dy: Day_Number;
Seconds: Day_Duration; -- seconds past midnight
BEGIN
Now := Clock;
Split (Now, Yr, Mo, Dy, Seconds);
Return ( ABS INTEGER(Seconds) mod 1000) ;
END Random;
PROCEDURE Start IS
-- Create a random sized room and reset the spider.
BEGIN
RoomSize := (Random MOD (RowHi-1)) + 2;
DrawRoom(RoomSize);
Row := 1;
Column := 1;
RowHi := RoomSize;
ColHi := RoomSize*2-1;
Heading := east;
Green;
ShowSpider;
ShowDirection;
END Start;
-- Color commands
PROCEDURE Blue IS
BEGIN
ChgColor (blue);
END Blue;
PROCEDURE Green IS
BEGIN
ChgColor (green);
END Green;
PROCEDURE Red IS
BEGIN
ChgColor (red);
END Red;
PROCEDURE Black IS
BEGIN
ChgColor (black);
END Black;
PROCEDURE Step IS
-- Take a step forward command.
OB : boolean := false; -- out of bounds flag
AnyThing: character;
Hit_The_Wall: exception;
BEGIN
-- put a block down where spider is standing
MoveCursor(Row+1,Column+WindowOffset);
Text_IO.Put (ColorSymbols (Ink) );
-- Check for out of bounds
CASE heading IS
WHEN north => IF Row <= LoBound THEN OB := true; END IF;
WHEN east => IF Column >= ColHi THEN OB := true; END IF;
WHEN south => IF Row >= RowHi THEN OB := true; END IF;
WHEN west => IF Column <= LoBound THEN OB := true; END IF;
END CASE;
-- If out of bounds raise and exception.
IF OB THEN
Text_IO.New_Line;
Quit;
raise Hit_The_Wall;
END IF;
-- change the location coordinates
CASE heading IS
WHEN north => Row := Row - 1;
WHEN east => Column := Column + 2;
WHEN south => Row := Row + 1;
WHEN west => Column := Column - 2;
END CASE;
-- draw the spider in her new location
ShowSpider;
IF Debug THEN -- if debug mode, wait for user to press return
WHILE NOT Text_IO.End_of_line LOOP
Text_IO.Get ( Anything );
END LOOP;
Text_IO.Skip_Line;
END IF;
END Step;
PROCEDURE Turn IS
-- Turn to the right command.
BEGIN
IF Heading = Direction'Last THEN
Heading := Direction'First;
ELSE Heading := Direction'succ (Heading);
END IF;
ShowDirection;
END Turn;
FUNCTION AtWall return BOOLEAN IS
-- RETURN True if spider is adjacent to and facing a wall.
BEGIN
-- Check for out of bounds
CASE heading IS
WHEN north => return Row <= LoBound;
WHEN east => return Column >= ColHi;
WHEN south => return Row >= RowHi;
WHEN west => return Column <= LoBound;
END CASE;
END AtWall;
PROCEDURE Quit IS
-- Quit command.
BEGIN
MoveCursor(24,1);
END Quit;
PROCEDURE Debug (Setting: Switch) is
-- Toggle debugging mode
BEGIN
IF Setting = ON THEN
DebugFlag := true;
MoveCursor (10,1);
Text_io.Put ("-- DEBUG ON -- ");
Text_io.New_Line;
Text_IO.Put (" Press Enter");
ELSE
DebugFlag := false;
MoveCursor (10,1);
Text_io.Put (" ");
Text_io.New_Line;
Text_IO.Put (" ");
END IF;
END Debug;
FUNCTION Debug return boolean is
BEGIN
Return DebugFlag;
END Debug;
END Spider;